/*
 * Copyright (c) 2023 fred
 * Licensed under the Apache License,Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import { Attributes } from '../nodes/Attributes';

/**
 * Controls parser case settings, to optionally preserve tag and/or attribute name case.
 */
export class ParseSettings {
  /**
   * HTML default settings: both tag and attribute names are lower-cased during parsing.
   */
  public static htmlDefault: ParseSettings;
  /**
   * Preserve both tag and attribute case.
   */
  public static preserveCase: ParseSettings;


  private static _initializer = (() => {
    ParseSettings.htmlDefault = new ParseSettings(false, false)
    ParseSettings.preserveCase = new ParseSettings(true, true)
  })();

  private readonly _preserveTagCase: boolean;
  private readonly _preserveAttributeCase: boolean;

  /**
   * Define parse settings.
   * @param tag preserve tag case?
   * @param attribute preserve attribute name case?
   */
  constructor(tag: boolean, attribute: boolean) {
    this._preserveTagCase = tag
    this._preserveAttributeCase = attribute
  }

  /**
   * Returns true if preserving tag name case.
   */
  public preserveTagCase(): boolean {
    return this._preserveTagCase;
  }

  /**
   * Returns true if preserving attribute case.
   */
  public preserveAttributeCase(): boolean {
    return this._preserveAttributeCase;
  }

  /**
   * Normalizes a tag name according to the case preservation setting.
   */
  public normalizeTag(name: string): string {
    name = name.trim();
    if (!this._preserveTagCase) {
      name = name.toLowerCase();
    }

    return name;
  }

  /**
   * Normalizes an attribute according to the case preservation setting.
   */
  public normalizeAttribute(name: string): string {
    name = name.trim();
    if (!this._preserveAttributeCase) {
      name = name.toLowerCase();
    }
    return name;
  }

  normalizeAttributes(attributes: Attributes): Attributes {
    if (attributes !== undefined && attributes !== null && !this._preserveAttributeCase) {
      attributes.normalize();
    }
    return attributes;
  }

  static normalName(name: string): string {
    return name.trim().toLowerCase();
  }
}
